import { Config } from "../../src/config/Config";
import { GameConfig } from "../../src/config/GameConfig";
import { RoomConfig } from "../../src/config/RoomConfig";
import { ServerConfig } from "../../src/config/ServerConfig";
import { Logger } from "../../src/engine/utils/Logger";
import RandomUtil from "../../src/engine/utils/RandomUtil";
import { JhaoProto } from "../../src/lib/net/protobuf/jhaoproto";
import { ServerManager } from "../../src/server/ServerManager";
import { RoomDao } from "../dao/RoomDao";
import { RoomEntity } from "../entity/RoomEntity";
import { GameResult } from "./GameResult";
import { RoomGameInfo } from "./RoomGameInfo";
import { RoomPlayer } from "./RoomPlayer";

export class RoomModel {

    public static roomMap: Map<number, JhaoProto.IRoomModel> = new Map<number, JhaoProto.IRoomModel>();

    public name: string;
    public room_id: number;
    public roomType: number = 0;
    public creator: number = 0 //房主用户id
    public create_time: number;
    public state: number;
    public clubid: number = 0;
    public num_of_turns: number = 0;
    public gameType: number;
    public server_id: number;
    public conf: object
    public playerList: Array<RoomPlayer> = []
    public game_info: RoomGameInfo = new RoomGameInfo()
    public bankerChair: number = 0
    public current_chair: number = 0
    public gameResult: GameResult = new GameResult();
    public lastCheckAutoReadyTIme: number = 0


    public static generateRoomId() {
        let room_id: number = RandomUtil.nextInt(100000, 999999)
        if (this.roomMap.has(room_id)) {
            return this.generateRoomId();
        }
        return room_id
    }

    public static async init() {
        let rows: Array<object> = await RoomDao.get_all_room()
        this.roomMap.clear()
        for (let i = 0; i < rows.length; i++) {
            this.initOneRoom(rows[i], true)
        }
        Logger.log("RoomDao.get_all_roo===", this.roomMap)
    }

    public static initOneRoom(obj: object, forceInit: boolean = false) {
        let model: JhaoProto.IRoomModel = {

        }
        model.serverId = obj["server_id"]
        let needInit: boolean = false
        if (ServerConfig.nowServerConfig.serverType == Config.ServerType_List.hall_server) {
            needInit = true
        } else {
            if (model.serverId == ServerConfig.nowServerConfig.id) {
                needInit = true
            }
        }
        if (needInit || forceInit) {
            model.roomId = obj["room_id"]
            model.name = obj["name"]
            model.creator = obj["creator"]
            model.roomType = obj["roomType"]
            model.createTime = new Date(obj["create_time"]).getTime()
            model.clubid = obj["clubid"]
            model.numOfTurns = obj["num_of_turns"]
            model.gameType = obj["game_type"]
            model.playerList = []
            model.roomConfigBase = JSON.parse(obj["conf_base"]) as JhaoProto.IRoomConfigBase
            model.gameInfoBase = JSON.parse(obj["game_info_base"]) as JhaoProto.IRoomGameInfoBase
            if(model.gameType == GameConfig.Game_Type.Mj){
                model.roomConfigMj = JSON.parse(obj["config_game"]) as JhaoProto.IRoomConfigMj
                model.gameInfoMj = JSON.parse(obj["config_game"]) as JhaoProto.IRoomGameInfoMj
            }
            model.playerList = JSON.parse(obj["playerList"])
            this.roomMap.set(model.roomId, model)
        }
        if (RoomModel.getPlayerNum(model) <= 0) {
            this.roomMap.delete(model.roomId)
        }
        // Logger.log("initOneRoom===", model)
        return model
    }

    public static async insertRoom(model: JhaoProto.IRoomModel) {
        let entity: RoomEntity = await RoomDao.insert_room(model)
        return entity;
    }

    public static insertPlayer(player: JhaoProto.IRoomPlayer, room: JhaoProto.IRoomModel) {
        for (let i = 0; i < room.playerList.length; i++) {
            if (room.playerList[i] && room.playerList[i].userid == player.userid) {
                player.chair = i;
                room.playerList[i] = player;
                return true
            }
        }
        let renshu: number = room.roomConfigBase.renshu
        for (let i = 0; i < renshu; i++) {
            if (!room.playerList[i]) {
                player.chair = i
                room.playerList[i] = player;
                return true
            }
        }
    }

    public leavePlayer(userid: number) {
        for (let i = 0; i < this.playerList.length; i++) {
            if (this.playerList[i] && this.playerList[i].userid == userid) {
                this.playerList[i] = null;
                return true
            }
        }
    }

    public getPlayerByUserid(userid: number) {
        for (let i = 0; i < this.playerList.length; i++) {
            if (this.playerList[i] && this.playerList[i].userid == userid) {
                return this.playerList[i]
            }
        }
    }

    public getPlayerByChair(chair: number) {
        for (let i = 0; i < this.playerList.length; i++) {
            if (this.playerList[i] && this.playerList[i].chair == chair) {
                return this.playerList[i]
            }
        }
    }

    public hadPlayer(userid: number) {
        for (let i = 0; i < this.playerList.length; i++) {
            if (this.playerList[i] && this.playerList[i].userid == userid) {
                return true
            }
        }
    }

    public static getPlayerNum(room:JhaoProto.IRoomModel) {
        let num: number = 0
        for (let i = 0; i < room.playerList.length; i++) {
            if (room.playerList[i]) {
                num++
            }
        }
        return num
    }

    public isAllReady() {
        let readyNum: number = 0
        for (let i = 0; i < this.playerList.length; i++) {
            if (this.playerList[i] && this.playerList[i].ready) {
                readyNum++
            }
        }
        if (readyNum >= this.conf["renshu"]) {
            return true
        }
    }

    public nextChair() {
        this.game_info.current_chair++;
        if (this.game_info.current_chair >= this.playerList.length) {
            this.game_info.current_chair = 0
        }
        // if (this.game_info.handCardList[this.game_info.current_chair].length <= 0) {
        //     this.nextChair();
        // }
    }

    public nextBanker() {
        this.bankerChair++
        if (this.bankerChair >= this.playerList.length) {
            this.bankerChair = 0
        }
    }

    public nextCurrentChair() {
        this.current_chair++
        if (this.current_chair >= this.playerList.length) {
            this.current_chair = 0
        }
    }

    public static getRoomListByClubid(clubid: number) {
        let roomList: Array<RoomModel> = []
        this.roomMap.forEach((model: RoomModel, key: number) => {
            if (model.clubid == clubid) {
                roomList.push(model)
            }
        });
        return roomList;
    }

    public static getRoomListZiyou(level: number) {
        let roomList: Array<RoomModel> = []
        this.roomMap.forEach((model: RoomModel, key: number) => {
            if (model.roomType == RoomConfig.Room_Type.Ziyou) {
                if (model.conf["level"] == level) {
                    roomList.push(model)
                }
            }
        });
        return roomList;
    }

    public static getRoomByRoomTypeAndLevel(roomType: number, gameType: number, level: number, renshu: number) {
        let result: RoomModel
        this.roomMap.forEach((model: RoomModel, key: number) => {
            if (model.roomType == roomType) {
                if (model.gameType == gameType) {
                    let config: RoomConfig = model.conf as RoomConfig
                    if (config.level == level && config.renshu == renshu) {
                        if (RoomModel.getPlayerNum(model) < config.renshu) {
                            result = model
                            return model
                        }
                    }
                }
            }
        });
        return result;
    }

    public static getRoomByRoomType(roomType: number, gameType: number) {
        let result: RoomModel
        this.roomMap.forEach((model: RoomModel, key: number) => {
            if (model.roomType == roomType) {
                if (model.gameType == gameType) {
                    let config: RoomConfig = model.conf as RoomConfig
                    if (RoomModel.getPlayerNum(model) < config.renshu) {
                        result = model
                        return model
                    }
                }
            }
        });
        return result;
    }


    public static getRoomOnlineNumByGameType(roomType: number, gameType: number, level: number) {
        let online: number = 0
        this.roomMap.forEach((model: RoomModel, key: number) => {
            if (model.roomType == roomType) {
                if (model.gameType == gameType) {
                    let config: RoomConfig = model.conf as RoomConfig
                    if (config.level == level) {
                        online += RoomModel.getPlayerNum(model)
                    }
                }
            }
        });
        return online
    }

    public static getRoomOnlineByRoomType(roomType: number, level: number) {
        let online: number = 0
        this.roomMap.forEach((model: RoomModel, key: number) => {
            if (model.roomType == roomType) {
                let config: RoomConfig = model.conf as RoomConfig
                if (config.level == level) {
                    online += RoomModel.getPlayerNum(model)
                }
            }
        });
        return online
    }

    public static getRoomOnlineNumByRoomTypeAndGameType(roomType: number, gameType: number) {
        let online: number = 0
        this.roomMap.forEach((model: RoomModel, key: number) => {
            if (model.roomType == roomType) {
                if (model.gameType == gameType) {
                    online += RoomModel.getPlayerNum(model)
                }
            }
        });
        return online
    }

    public static isInRoom(userid: number) {
        // let inRoom:boolean = false
        let roomId: number = 0
        this.roomMap.forEach((model: RoomModel, key: number) => {
            for (let i = 0; i < model.playerList.length; i++) {
                if (model.playerList[i] && model.playerList[i].userid == userid) {
                    roomId = model.room_id
                    return roomId
                }
            }
        });
        return roomId
    }
}